<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML>
<HEAD>
<TITLE>80386 Programmer's Reference Manual -- Section 8.3</TITLE>
</HEAD>
<BODY STYLE="width:80ch">
<B>up:</B> <A HREF="c08.htm">
Chapter 8 -- Input/Output</A><BR>
<B>prev:</B> <A HREF="s08_02.htm">8.2  I/O Instructions</A><BR>
<B>next:</B> <A HREF="c09.htm">Chapter 9 -- Exceptions and Interrupts</A>
<P>
<HR>
<P>
<H1>8.3  Protection and I/O</H1>
Two mechanisms provide protection for I/O functions:
<OL>
<LI> The IOPL field in the EFLAGS register defines the right to use
I/O-related instructions.
<LI> The I/O permission bit map of a 80386 TSS segment defines the right
to use ports in the I/O address space.
</OL>
These mechanisms operate only in protected mode, including virtual 8086
mode; they do not operate in real mode. In real mode, there is no protection
of the I/O space; any procedure can execute I/O instructions, and any I/O
port can be addressed by the I/O instructions.

<H2>8.3.1  I/O Privilege Level</H2>
Instructions that deal with I/O need to be restricted but also need to be
executed by procedures executing at privilege levels other than zero. For
this reason, the processor uses two bits of the flags register to store the
I/O privilege level (IOPL). The IOPL defines the privilege level
needed to execute I/O-related instructions.
<P>
The following instructions can be executed only if CPL <= IOPL:
<UL>
<LI> <A HREF="IN.htm">IN</A> -- Input
<LI> <A HREF="INS.htm">INS</A> -- Input String
<LI> <A HREF="OUT.htm">OUT</A> -- Output
<LI> <A HREF="OUTS.htm">OUTS</A> -- Output String
<LI> <A HREF="CLI.htm">CLI</A> -- Clear Interrupt-Enable Flag
<LI> <A HREF="STI.htm">STI</A> -- Set Interrupt-Enable
</UL>
These instructions are called "sensitive" instructions, because they are
sensitive to IOPL.
<P>
To use sensitive instructions, a procedure must execute at a privilege
level at least as privileged as that specified by the IOPL (CPL <= IOPL). Any
attempt by a less privileged procedure to use a sensitive instruction
results in a general protection exception.
<P>
Because each task has its own unique copy of the flags register, each task
can have a different IOPL. A task whose primary function is to perform I/O
(a device driver) can benefit from having an IOPL of three, thereby
permitting all procedures of the task to perform I/O. Other tasks typically
have IOPL set to zero or one, reserving the right to perform I/O
instructions for the most privileged procedures.
<P>
A task can change IOPL only with the 
<A HREF="POPF.htm">POPF</A> instruction; however, such
changes are privileged. No procedure may alter IOPL (the I/O privilege level
in the flag register) unless the procedure is executing at privilege level
0. An attempt by a less privileged procedure to alter IOPL does not result
in an exception; IOPL simply remains unaltered.
<P>
The <A HREF="POPF.htm">POPF</A> instruction may be used in addition to 
<A HREF="CLI.htm">CLI</A> and <A HREF="STI.htm">STI</A> to alter the
interrupt-enable flag (IF); however, changes to IF by 
<A HREF="POPF.htm">POPF</A> are
IOPL-sensitive. A procedure may alter IF with a 
<A HREF="POPF.htm">POPF</A> instruction only when
executing at a level that is at least as privileged as IOPL. An attempt by a
less privileged procedure to alter IF in this manner does not result in an
exception; IF simply remains unaltered.

<H2>8.3.2  I/O Permission Bit Map</H2>
The I/O instructions that directly refer to addresses in the processor's
I/O space are 
<A HREF="IN.htm">IN</A>, 
<A HREF="INS.htm">INS</A>, 
<A HREF="OUT.htm">OUT</A>, 
<A HREF="OUTS.htm">OUTS</A>. The 80386 has the ability to selectively
trap references to specific I/O addresses. The structure that enables
selective trapping is the I/O Permission Bit Map in the TSS segment (see
<A HREF="s08_03.htm#fig8-2">Figure 8-2</A>). 
The I/O permission map is a bit vector. The size of the map
and its location in the TSS segment are variable. The processor locates the
I/O permission map by means of the I/O map base field in the fixed portion
of the TSS. The I/O map base field is 16 bits wide and contains the offset
of the beginning of the I/O permission map. The upper limit of the I/O
permission map is the same as the limit of the TSS segment.
<P>
In protected mode, when it encounters an I/O instruction 
(<A HREF="IN.htm">IN</A>, 
<A HREF="INS.htm">INS</A>, 
<A HREF="OUT.htm">OUT</A>, or
<A HREF="OUTS.htm">OUTS</A>), the processor first checks whether CPL <= IOPL. 
If this condition is
true, the I/O operation may proceed. If not true, the processor checks the
I/O permission map. (In virtual 8086 mode, the processor consults the map
without regard for IOPL . Refer to 
<A HREF="c15.htm">Chapter 15</A>.)
<P>
Each bit in the map corresponds to an I/O port byte address; for example,
the bit for port 41 is found at I/O map base + 5, bit offset 1. The
processor tests all the bits that correspond to the I/O addresses spanned by
an I/O operation; for example, a doubleword operation tests four bits
corresponding to four adjacent byte addresses. If any tested bit is set,
the processor signals a general protection exception. If all the tested bits
are zero, the I/O operation may proceed.
<P>
It is not necessary for the I/O permission map to represent all the I/O
addresses. I/O addresses not spanned by the map are treated as if they had
one bits in the map. For example, if TSS limit is equal to I/O map base +
31, the first 256 I/O ports are mapped; I/O operations on any port greater
than 255 cause an exception.
<P>
If I/O map base is greater than or equal to TSS limit, the TSS segment has
no I/O permission map, and all I/O instructions in the 80386 program cause
exceptions when CPL > IOPL.
<P>
Because the I/O permission map is in the TSS segment, different tasks can
have different maps. Thus, the operating system can allocate ports to a task
by changing the I/O permission map in the task's TSS.
<P>
<A NAME="fig8-2">
<PRE>Figure 8-2.  I/O Address Bit Map</PRE>
<P>
<PRE>
                                    TSS SEGMEMT

                        31       23       15       7      0
                       +--------+--------+--------+--------+
              LIMIT--->|                                   |
                       | - - - - - - - - - - - - - - - - - |
                       *                                   *
                       *      I/O PERMISSION BIT MAP       *
                       *                                   *
                       | - - - - - - - - - - - - - - - - - |
                 +---->|                                   |
                 |     |--------+--------+--------+--------|
                 |     *                                   *
                 |     *                                   *
                 |     *                                   *
                 |     |--------+--------+--------+--------|
                 +-----|  I/O MAP BASE   |uuuuuuuu uuuuuuuT|64
                       |--------+--------+--------+--------|
                       |00000000 00000000|       LOT       |60
                       |--------+--------+--------+--------|
                       |00000000 00000000|       GS        |5C
                       |--------+--------+--------+--------|
                       |                                   |58
                       *                                   *
                       *                                   *
                       *                                   *
                       |                                   |4
                       |--------+--------+--------+--------|
                       |00000000 00000000|  TSS BACK LINK  |0
                       +--------+--------+--------+--------+
</PRE>
<P>
<HR>
<P>
<B>up:</B> <A HREF="c08.htm">
Chapter 8 -- Input/Output</A><BR>
<B>prev:</B> <A HREF="s08_02.htm">8.2  I/O Instructions</A><BR>
<B>next:</B> <A HREF="c09.htm">Chapter 9 -- Exceptions and Interrupts</A>
</BODY>
